﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using MimiDouban.Test;

namespace MimiDouban.UI.SkinManager
{
    /// <summary>
    /// 皮肤管理器，单例模式实现
    /// </summary>
    public class SkinManager
    {
        /// <summary>
        /// 皮肤的存放路径
        /// </summary>
        private static readonly string SKIN_DIR = "Resources\\skins";

        /// <summary>
        /// 默认皮肤
        /// </summary>
        private Skin defaultSkin;

        /// <summary>
        /// 所有的皮肤列表
        /// </summary>
        private List<Skin> skins = new List<Skin>();

        /// <summary>
        /// 皮肤目录
        /// </summary>
        private string skinDir;
        private bool initialized = false;
        private int nextIndex = 0;        

        private static SkinManager uniqueInstance;

        /// <summary>
        /// 获取所有皮肤
        /// </summary>
        public List<Skin> Skins
        {
            get { return skins; }
        }

        private SkinManager()
        {
            string defaultSkinStr = "<Brushes><SolidColorBrush Key=\"skinPanelBackgroud\" Color=\"#FF000000\"></SolidColorBrush>" +
                "<SolidColorBrush Key=\"skinMainBackgroud\" Color=\"#FF000000\"></SolidColorBrush>" +
                "<SolidColorBrush Key=\"skinChannelBackgroud\" Color=\"#FF000000\"></SolidColorBrush>" +
                "<SolidColorBrush Key=\"skinLoginBackgroud\" Color=\"#FF000000\"></SolidColorBrush>" +
                "<SolidColorBrush Key=\"skinBorder\" Color=\"#FFAAAAAA\"></SolidColorBrush>" +
                "<SolidColorBrush Key=\"skinTitle\" Color=\"#FFFFFFFF\"></SolidColorBrush>" +
                "<SolidColorBrush Key=\"skinMessageBorder\" Color=\"#FFFFFFFF\"></SolidColorBrush>" +
                "<SolidColorBrush Key=\"skinMessage\" Color=\"#FFDFFBA7\"></SolidColorBrush>" +
                "<SolidColorBrush Key=\"skinDownload\" Color=\"#FF7D8078\"></SolidColorBrush>" +
                "<SolidColorBrush Key=\"skinTextBox\" Color=\"#FF000000\"></SolidColorBrush>" +
                "<SolidColorBrush Key=\"skinBottonBackground\" Color=\"#FF000000\"></SolidColorBrush></Brushes>";
            defaultSkin = readSkin(new MemoryStream(Encoding.UTF8.GetBytes(defaultSkinStr)));
            defaultSkin.SkinId = "_defaultSkin";
            this.skinDir = SKIN_DIR;
        }

        public static SkinManager getInstance()
        {
            if (uniqueInstance == null)
            {
                uniqueInstance = new SkinManager();
                uniqueInstance.init();
            }
            return uniqueInstance;
        }

        /// <summary>
        /// 获取下一个皮肤
        /// </summary>
        /// <returns>下一个皮肤</returns>
        public Skin getNextSkin()
        {
            init();
            if (nextIndex < skins.Count)
            {
                return skins[nextIndex++];
            }
            else
            {
                nextIndex = 0;
                return defaultSkin;
            }
        }


        /// <summary>
        /// 读取指定Id的皮肤
        /// </summary>
        /// <param name="skinId">指定Id</param>
        /// <returns></returns>
        public Skin getSkinWithID(string skinId)
        {
            if (skinId == null)
            {
                return defaultSkin;
            }

            foreach (Skin s in this.skins)
            {
                if (s.SkinId == skinId)
                {
                    return s;
                }
            }
            return defaultSkin;
        }

        /// <summary>
        /// 初始化，读取皮肤目录下所有皮肤
        /// </summary>
        private void init()
        {
            if (initialized)
            {
                return;
            }
            string[] allSkinDirs = Directory.GetDirectories(this.skinDir);
            foreach (string aSkinDir in allSkinDirs)
            {
                if (!aSkinDir.StartsWith(SKIN_DIR + "\\" + "skin_"))
                {
                    continue;
                }
                try
                {
                    string skinFile = aSkinDir + "\\skin.xml";
                    Skin aSkin = readSkin(File.Open(skinFile, FileMode.Open));
                    aSkin.SkinId = aSkinDir.Substring(SKIN_DIR.Length);
                    this.skins.Add(aSkin);
                }
                catch (Exception e)
                {
                    TestLog.getInstance().error("读取皮肤失败", e);
                }
            }
            initialized = true;
        }

        private Skin readSkin(Stream skinStream)
        {
            XmlDocument xmlFile = new XmlDocument();
            xmlFile.Load(skinStream);

            Skin result = new Skin();

            //先处理所有的ImageBrushes
            XmlNodeList allImgBrushes = xmlFile.GetElementsByTagName("ImageBrush");
            foreach (XmlElement imgBru in allImgBrushes)
            {
                try
                {
                    ImageBrush newBrush = new ImageBrush();
                    newBrush.TileMode = TileMode.FlipX;
                    newBrush.Stretch = Stretch.Fill;
                    newBrush.ImageSource = new BitmapImage(new Uri(SKIN_DIR + "\\" + imgBru.Attributes["ImageSource"].Value, UriKind.Relative));
                    result.Brushes.Add(imgBru.Attributes["Key"].Value, newBrush);
                }
                catch
                {
                    continue;
                }
            }

            //在处理所有的SolidColorBrushes
            XmlNodeList allSolBrushes = xmlFile.GetElementsByTagName("SolidColorBrush");
            foreach (XmlElement solBru in allSolBrushes)
            {
                try
                {
                    SolidColorBrush newBrush;
                    string color = solBru.Attributes["Color"].Value;
                    Color newColor = Color.FromArgb(Convert.ToByte(color.Substring(1, 2), 16),
                        Convert.ToByte(color.Substring(3, 2), 16),
                        Convert.ToByte(color.Substring(5, 2), 16),
                        Convert.ToByte(color.Substring(7, 2), 16));
                    newBrush = new SolidColorBrush(newColor);
                    result.Brushes.Add(solBru.Attributes["Key"].Value, newBrush);
                }
                catch
                {
                    continue;
                }
            }

            return result;
        }
    }
}
